package stl

import (
	"path/filepath"
	"regexp"

	msmath "gitee.com/yrwy/msgo/pkg/math"
)

// insert in Array, Slice, or String
func InsertList[S ~[]E, E any](s S, pos int, i ...E) S {
	if len(i) < 1 {
		return s
	}
	if pos < 0 {
		r := make(S, 0, len(s)+len(i))
		r = append(r, i...)
		r = append(r, s...)
		return r
	}
	if pos < len(s) {
		r := make(S, 0, len(s)+len(i))
		r = append(r, s[:pos]...)
		r = append(r, i...)
		r = append(r, s[pos:]...)
		return r
	}
	return append(s, i...)
}

func IndexSlice[S ~[]T, T comparable](s S, v T, begin int) int {
	n := len(s)
	if begin < 0 {
		begin = 0
	}
	for begin < n {
		if s[begin] == v {
			return begin
		}
		begin++
	}
	return -1
}

func SliceHas[S ~[]T, T comparable](s S, v T) bool {
	return IndexSlice(s, v, 0) >= 0
}

func CountSlice[S ~[]T, T comparable](s S, v T) int {
	r := 0
	for _, val := range s {
		if val == v {
			r++
		}
	}
	return r
}

func SliceResize[S ~[]T, T any](s S, size int) []T {
	if size < 0 {
		return s
	}
	if len(s) < size {
		add_len := size - len(s)
		s = append(s, make([]T, add_len)...)
	}
	return s[:size]
}

func SliceReverse[S ~[]T, T any](s S) []T {
	for i := 0; i < len(s)/2; i++ {
		s[i], s[len(s)-i-1] = s[len(s)-i-1], s[i]
	}
	return s
}

func SliceMatchWith[S ~[]T, T any](s S, match func(T) bool) []T {
	var r []T
	for _, v := range s {
		if match(v) {
			r = append(r, v)
		}
	}
	return r
}

func StringSliceMatch(s []string, pattern string) []string {
	return SliceMatchWith(s, func(v string) bool {
		ok, _ := filepath.Match(pattern, v)
		return ok
	})
}

func StringSliceMatchWildcard(s []string, pattern string) []string {
	return SliceMatchWith(s, func(v string) bool {
		return msmath.MatchWildcard(pattern, v)
	})
}

func StringSliceMatchReg(s []string, reg *regexp.Regexp) []string {
	return SliceMatchWith(s, func(v string) bool {
		return reg.MatchString(v)
	})
}
